package com.ssy.lingxi.member.merchant.serviceimpl.feign;

import cn.hutool.json.JSONUtil;
import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.component.redis.service.IRedisStringUtils;
import com.ssy.lingxi.member.merchant.api.constant.AuthTypeEnum;
import com.ssy.lingxi.member.merchant.api.constant.BaiDuConfigEnum;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.request.AuthConfigVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.request.DeleteAuthConfigVO;
import com.ssy.lingxi.member.merchant.entity.MemberAuthTypeConfigDO;
import com.ssy.lingxi.member.merchant.repository.MemberAuthTypeConfigFeignRepository;
import com.ssy.lingxi.member.merchant.service.feign.IMemberAuthTypeConfigFeignService;
import com.ssy.lingxi.sms.api.common.AliConfigEnum;
import com.ssy.lingxi.sms.api.common.ServiceTypeEnum;
import com.ssy.lingxi.sms.api.common.StatusEnum;
import com.ssy.lingxi.sms.api.common.TencentConfigEnum;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;

/**
 * 实名验证配置类
 *
 * @author lqa
 * @version 2.0.0
 * @date 2022/1/13
 */
@Service
public class MemberAuthTypeConfigFeignServiceImpl implements IMemberAuthTypeConfigFeignService {
    @Resource
    private IRedisStringUtils redisStringUtils;
    @Resource
    private MemberAuthTypeConfigFeignRepository memberAuthTypeConfigFeignRepository;

    /**
     * 查询生效的配置信息
     *
     * @return MemberAuthDO
     */
    @Override
    public MemberAuthTypeConfigDO findEnableAuthConfig() {
        MemberAuthTypeConfigDO memberAuthTypeConfigDO = null;
        //先从redis缓存中查找配置信息
        String json = redisStringUtils.hGet(Constants.REDIS_KEY_AUTH_SERVICE, Constants.REDIS_AUTH_CONFIG, Constants.REDIS_USER_INDEX);
        if (StringUtils.isNotEmpty(json)) {
            memberAuthTypeConfigDO = JSONUtil.toBean(json, MemberAuthTypeConfigDO.class);
        }
        //从redis缓存中获取不到配置信息,则从数据库中查找
        if (memberAuthTypeConfigDO == null) {
            memberAuthTypeConfigDO = memberAuthTypeConfigFeignRepository.findByStatus(StatusEnum.ENABLED.getCode());
        }
        return memberAuthTypeConfigDO;
    }

    /**
     * 添加或修改实名验证公共参数
     *
     * @param authConfigVO 实名验证公共参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Boolean saveOrUpdateAuthConfig(AuthConfigVO authConfigVO) {

        Integer authType = authConfigVO.getAuthType();
        String code = authConfigVO.getCode();
        String value = authConfigVO.getValue();
        String remark = authConfigVO.getRemark();
        //校验参数代码是否合法
        Boolean flag = checkLegal(authType, code);
        if (!flag) {
            throw new BusinessException(ResponseCode.MC_MS_AUTH_CONFIG_ILLEGAL);
        }
        //查询数据库是否存在该数据
        HashMap<String, Object> configMap;
        MemberAuthTypeConfigDO memberAuthTypeConfigDO = memberAuthTypeConfigFeignRepository.findTopByAuthTypeOrderByIdDesc(authType);
        if (memberAuthTypeConfigDO == null) {
            configMap = new HashMap<>();
            memberAuthTypeConfigDO = new MemberAuthTypeConfigDO();
            memberAuthTypeConfigDO.setAuthType(authType);
        } else {
            configMap = memberAuthTypeConfigDO.getConfig();
        }
        configMap.put(code, value + "|" + remark);
        memberAuthTypeConfigDO.setConfig(configMap);
        memberAuthTypeConfigDO.setStatus(true);
        //数据库持久化对象
        memberAuthTypeConfigFeignRepository.saveAndFlush(memberAuthTypeConfigDO);
        //将其他实名验证状态改为false
        List<MemberAuthTypeConfigDO> memberAuthTypeConfigDOList = memberAuthTypeConfigFeignRepository.findByIdNot(memberAuthTypeConfigDO.getId());
        if (memberAuthTypeConfigDOList.size() > 0) {
            memberAuthTypeConfigDOList.forEach(p -> p.setStatus(StatusEnum.DISABLED.getCode()));
            memberAuthTypeConfigFeignRepository.saveAll(memberAuthTypeConfigDOList);
            memberAuthTypeConfigFeignRepository.flush();
        }
        //只有在启用的情况才需要将最新配置存入redis缓存中
        Boolean status = memberAuthTypeConfigDO.getStatus();
        if (status) {
            redisStringUtils.hSet(Constants.REDIS_KEY_AUTH_SERVICE, Constants.REDIS_AUTH_CONFIG, JSONUtil.toJsonStr(memberAuthTypeConfigDO), Constants.REDIS_USER_INDEX);
        }
        return true;
    }

    /**
     * 删除实名验证公共参数
     *
     * @param deleteAuthConfigVO 请求参数
     * @return 操作结果
     */
    @Override
    public Boolean deleteAuthConfig(DeleteAuthConfigVO deleteAuthConfigVO) {
        Integer authType = deleteAuthConfigVO.getAuthType();
        String code = deleteAuthConfigVO.getCode();
        //检查参数代码是否合法
        Boolean flag = checkLegal(authType, code);
        if (!flag) {
            throw new BusinessException(ResponseCode.MC_MS_AUTH_CONFIG_ILLEGAL);
        }
        //查询数据库是否存在该数据
        MemberAuthTypeConfigDO memberAuthTypeConfigDO = memberAuthTypeConfigFeignRepository.findTopByAuthTypeOrderByIdDesc(authType);
        if (memberAuthTypeConfigDO != null) {
            HashMap<String, Object> configMap = memberAuthTypeConfigDO.getConfig();
            if (configMap != null && configMap.containsKey(code)) {
                configMap.remove(code);
                memberAuthTypeConfigDO.setConfig(configMap);
                //数据库持久化对象
                memberAuthTypeConfigFeignRepository.saveAndFlush(memberAuthTypeConfigDO);
                //只有启用的情况才需要将最新配置存入redis缓存中
                Boolean status = memberAuthTypeConfigDO.getStatus();
                if (status) {
                    redisStringUtils.hSet(Constants.REDIS_KEY_AUTH_SERVICE, Constants.REDIS_AUTH_CONFIG, JSONUtil.toJsonStr(memberAuthTypeConfigDO), Constants.REDIS_USER_INDEX);
                }
                return true;
            } else {
                throw new BusinessException(ResponseCode.MC_MS_AUTH_CONFIG_CODE_NOT_EXIST);
            }
        } else {
            throw new BusinessException(ResponseCode.MC_MS_AUTH_CONFIG_NOT_EXIST);
        }
    }
    /**
     * 清空实名验证内容
     *
     * @return 是否成功
     */
    @Override
    public Boolean clearAuth() {
        memberAuthTypeConfigFeignRepository.deleteAllInBatch();
        return true;
    }

    /**
     * 校验参数代码是否正确
     *
     * @param authType 实名验证类型: 1-百度
     * @param code     配置参数名
     * @return 是否正确
     */
    private Boolean checkLegal(Integer authType, String code) {
        if (authType.equals(AuthTypeEnum.BAI_DU.getCode())) {
            return BaiDuConfigEnum.getMessage(code);
        }
        return false;
    }
}
